package com.atguigu.gmall.payment.service.impl;

import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.mapper.PaymentInfoMapper;
import com.atguigu.gmall.payment.service.PaymentService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

@Service
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentInfoMapper paymentInfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitService rabbitService;

    @Override
    public void savePaymentInfo(OrderInfo orderInfo, String paymentType) {
        //  交易记录表.  一个订单Id 和 支付类型 不能有多条一样的！
        QueryWrapper<PaymentInfo> paymentInfoQueryWrapper = new QueryWrapper<>();
        paymentInfoQueryWrapper.eq("order_id", orderInfo.getId());
        paymentInfoQueryWrapper.eq("payment_type", paymentType);
        PaymentInfo paymentInfoQuery = paymentInfoMapper.selectOne(paymentInfoQueryWrapper);
        //  如果有当前订单以及支付方式的记录，则返回，否则插入信息.
        if (paymentInfoQuery != null) return;

        //创建paymentInfo对象
        PaymentInfo paymentInfo = new PaymentInfo();
        //赋值paymentInfo
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setOrderId(orderInfo.getId());
        paymentInfo.setUserId(orderInfo.getUserId()); // userId 通常都会在控制器中获取。 直接获取.
        paymentInfo.setPaymentType(paymentType);
        paymentInfo.setTotalAmount(orderInfo.getTotalAmount());
        paymentInfo.setSubject(orderInfo.getTradeBody());
        paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());
        // callback_time callback_content 异步回调的时候，再给值.

        paymentInfoMapper.insert(paymentInfo);
    }

    @Override
    public void paySuccess(String outTradeNo, String paymentType, Map<String, String> paramMap) {
        //  先查询一下当前是否有对应的交易记录. 正常应该是有数据.
        PaymentInfo paymentInfoQuery = this.getPaymentInfo(outTradeNo, paymentType);
        if (paymentInfoQuery == null) {
            return;
        }
        try {
            //  更新数据。
            //            UpdateWrapper<PaymentInfo> paymentInfoUpdateWrapper = new UpdateWrapper<>();
            //            paymentInfoUpdateWrapper.eq("out_trade_no",outTradeNo);
            //            paymentInfoUpdateWrapper.eq("payment_type",paymentType);
            PaymentInfo paymentInfo = new PaymentInfo();
            //        paymentInfo.setOutTradeNo(outTradeNo);
            //        paymentInfo.setPaymentType(paymentType);
            //  更新支付宝的交易号.
            paymentInfo.setTradeNo(paramMap.get("trade_no"));
            paymentInfo.setCallbackTime(new Date());
            paymentInfo.setCallbackContent(paramMap.toString());
            paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());
            //  this.paymentInfoMapper.update(paymentInfo,paymentInfoUpdateWrapper);

            //  方法抽离：
            this.updatePaymentInfo(outTradeNo, paymentType, paymentInfo);
        } catch (Exception e) {
            //  由于网络抖动出现了异常......
            this.redisTemplate.delete(paramMap.get("notify_id"));
            e.printStackTrace();
        }
        //  发送一个消息给订单；告诉订单要更新状态. 发送一个订单Id
        this.rabbitService.sendMsg(MqConst.EXCHANGE_DIRECT_PAYMENT_PAY,MqConst.ROUTING_PAYMENT_PAY,paymentInfoQuery.getOrderId());

    }

    //  更新交易记录.
    @Override
    public void updatePaymentInfo(String outTradeNo, String paymentType, PaymentInfo paymentInfo) {
        UpdateWrapper<PaymentInfo> paymentInfoUpdateWrapper = new UpdateWrapper<>();
        paymentInfoUpdateWrapper.eq("out_trade_no", outTradeNo);
        paymentInfoUpdateWrapper.eq("payment_type", paymentType);
        paymentInfoMapper.update(paymentInfo, paymentInfoUpdateWrapper);
    }

    @Override
    public PaymentInfo getPaymentInfo(String outTradeNo, String paymentType) {
        QueryWrapper<PaymentInfo> paymentInfoQueryWrapper = new QueryWrapper<>();
        paymentInfoQueryWrapper.eq("out_trade_no", outTradeNo);
        paymentInfoQueryWrapper.eq("payment_type", paymentType);
        PaymentInfo paymentInfo = paymentInfoMapper.selectOne(paymentInfoQueryWrapper);
        //判断
        if (paymentInfo != null) {
            return paymentInfo;
        }
        return null;
    }

    //  关闭本地交易记录。
    @Override
    public void closePayment(Long orderId) {
        //本质：更新
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setPaymentStatus(PaymentStatus.CLOSED.name());
        paymentInfo.setUpdateTime(new Date());
        //更新条件
        UpdateWrapper<PaymentInfo> paymentInfoUpdateWrapper = new UpdateWrapper<>();
        paymentInfoUpdateWrapper.eq("order_id",orderId);
        paymentInfoMapper.update(paymentInfo,paymentInfoUpdateWrapper);

    }

}
